﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;

namespace MySQLLib
{
    public class Character
    {
        /*
         * 0: ID
         * 1: account
         * 2: name
         * 3: chartype
         * 4: volume
         * 5: level
         * 6: stength
         * 7: intelligence
         * 8: attribute
         * 9: hp
         * 10: mp
         * 11: gold
         * 12: experience
         * 13: spbar
         * 14: sp
         * 15: gm
         * 16: xsec
         * 17: ysec
         * 18: unknown
         * 19: xpos
         * 20: ypos
         * 21: zpos
         * 22: s_hp
         * 23: s_mp
         * 24: min_phyatk
         * 25: max_phyatk
         * 26: min_magatk
         * 27: max_magatk
         * 28: phydef
         * 29: magdef
         * 30: hit
         * 31: parry
         * 32: unknown
         * 33: walkspeed
         * 34: runspeed
         * 35: berserkspeed
         * 36: berserkbar
         * 37: unknown
         * 38: mag_absob
         * 39: phy_adsord
         * 40: save_area
         * 41: title
         * 42: deleted
         * 43: deletetime
         * 44: slots
         * 45: pvpstate
         * 46: action
         * 47: online
         * 48: dailypk
         * 49: pklevel
         * 50: murderlevel
         * 51: guidedata
         * 52: stallmodel
         * 53: storage_expanden
         * 
         */


        string[,] _character;
        private MySqlConnection conn;

        public int getCharId(string name, bool refresh = false)
        {
            if (refresh)
                this.refresh();
            
            int id;

            for (int i = 0; i < _character.GetLength(0); i++)
            {
                if (_character[i, 1] == name)
                {
                    Int32.TryParse(_character[i, 0], out id);
                    return id;
                }
            }

            return 0;
        }

        public string getAccountName(int id,bool refresh = false)
        {
            if (refresh)
                this.refresh();

            return this._character[id - 1,1];
        }

        public int getType(int id, bool refresh = false)
        {
            int type;

            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 3], out type);
            return type;
        }

        public int getVolume(int id,bool refresh = false)
        {
            int volume;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 4], out volume);
            return volume;
        }

        public int getLevel(int id, bool refresh = false)
        {
            int level;

            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1,5], out level);       

            return level;
        }

        public int getStrength(int id, bool refresh = false)
        {
            int strength;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1,6], out strength);

            return strength;
        }

        public int getIntellegence(int id, bool refresh = false)
        {
            int intelligence;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 7], out intelligence);

            return intelligence;
        }

        public int getAttributePoints(int id,bool refresh = false)
        {
            int points;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 8], out points);

            return points;
        }

        public Object getHP(int id, bool refresh = false, bool current = false, bool both = false)
        {
            if (refresh)
                this.refresh();

            if (!current && !both)
            {
                int hp;
                Int32.TryParse(_character[id - 1,9], out hp);
                return hp;
            }
            else if (current && !both)
            {
                int hp;
                Int32.TryParse(_character[id - 1, 22], out hp);
                return hp;
            }
            else
            {
                int[] hp = new int[2];
                Int32.TryParse(_character[id - 1, 9], out hp[0]);
                Int32.TryParse(_character[id - 1, 22], out hp[1]);
                return hp;
            }

        }

        public Object getMP(int id, bool refresh = false, bool current = false, bool both = false)
        {
            if (refresh)
                this.refresh();

            if (!current && !both)
            {
                int mp;
                Int32.TryParse(_character[id - 1, 10], out mp);
                return mp;
            }
            else if (current && !both)
            {
                int mp;
                Int32.TryParse(_character[id - 1, 23], out mp);
                return mp;
            }
            else
            {
                int[] mp = new int[2];
                Int32.TryParse(_character[id - 1, 10], out mp[0]);
                Int32.TryParse(_character[id - 1, 23], out mp[1]);
                return mp;
            }
        }

        public int getGold(int id, bool refresh = false)
        {
            int gold;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 11], out gold);

            return gold;
        }

        public int getExp(int id, bool refresh = false)
        {
            int exp;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 12], out exp);

            return exp;
        }

        public Object getSP(int id, bool refresh = false, bool bar = false, bool both = false)
        {
            if (refresh)
                this.refresh();

            if (!bar && !both)
            {
                int sp;
                Int32.TryParse(_character[id - 1, 14], out sp);
                return sp;
            }
            else if (bar && !both)
            {
                int sp;
                Int32.TryParse(_character[id - 1, 13], out sp);
                return sp;
            }
            else
            {
                int[] sp = new int[2];
                Int32.TryParse(_character[id - 1, 14], out sp[0]);
                Int32.TryParse(_character[id - 1, 13], out sp[1]);
                return sp;
            }
        }

        public bool isGM(int id, bool refresh = false)
        {
            bool gm = false;
            if (refresh)
                this.refresh();

            if (_character[id - 1, 15] == "1")
                gm = true;

            return gm;
        }

        public int[] getPos(int id, bool refresh = false)
        {
            int[] pos = new int[5];

            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 16], out pos[0]);
            Int32.TryParse(_character[id - 1, 17], out pos[1]);
            Int32.TryParse(_character[id - 1, 19], out pos[2]);
            Int32.TryParse(_character[id - 1, 20], out pos[3]);
            Int32.TryParse(_character[id - 1, 21], out pos[4]);

            return pos;
        }

        public int[] getSect(int id, bool refresh = false)
        {
            int[] sec = new int[2];
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 16], out sec[0]);
            Int32.TryParse(_character[id - 1, 17], out sec[1]);

            return sec;
        }

        public Object getPhyAtk(int id, bool refresh = false, bool min = false, bool both = false)
        {
            if (refresh)
                this.refresh();

            if (!min && !both)
            {
                int atk;
                Int32.TryParse(_character[id - 1, 25], out atk);
                return atk;
            }
            else if (min && !both)
            {
                int atk;
                Int32.TryParse(_character[id - 1, 24], out atk);
                return atk;
            }
            else
            {
                int[] atk = new int[2];
                Int32.TryParse(_character[id - 1, 25], out atk[0]);
                Int32.TryParse(_character[id - 1, 24], out atk[1]);
                return atk;
            }
        }

        public Object getMagAtk(int id, bool refresh = false, bool min = false, bool both = false)
        {
            if (refresh)
                this.refresh();

            if (!min && !both)
            {
                int atk;
                Int32.TryParse(_character[id - 1, 27], out atk);
                return atk;
            }
            else if (min && !both)
            {
                int atk;
                Int32.TryParse(_character[id - 1, 26], out atk);
                return atk;
            }
            else
            {
                int[] atk = new int[2];
                Int32.TryParse(_character[id - 1, 27], out atk[0]);
                Int32.TryParse(_character[id - 1, 26], out atk[1]);
                return atk;
            }
        }

        public int getPhyDef(int id, bool refresh = false)
        {
            int def;

            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 28], out def);

            return def;
        }

        public int getMagDef(int id, bool refresh = false)
        {
            int def;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 29], out def);

            return def;
        }

        public int getHitRation(int id, bool refresh = false)
        {
            int hit;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 30], out hit);

            return hit;
        }

        public int getParryRation(int id, bool refresh = false)
        {
            int parry;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 31], out parry);

            return parry;
        }

        public int[] getSpeed(int id, bool refresh = false)
        {
            int[] speed = new int[3];

            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 33], out speed[0]);
            Int32.TryParse(_character[id - 1, 34], out speed[1]);
            Int32.TryParse(_character[id - 1, 35], out speed[2]);

            return speed;
        }

        public int[] getAbsord(int id, bool refresh = false)
        {
            int[] absord = new int[2];

            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 38], out absord[0]);
            Int32.TryParse(_character[id - 1, 39], out absord[1]);

            return absord;
        }

        public int getSaveArea(int id, bool refresh = false)
        {
            int area;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 40], out area);

            return area;
        }

        public int getTitle(int id, bool refresh = false)
        {
            int title;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 41], out title);

            return title;
        }

        public string[] getDeleteStatus(int id, bool refresh = false)
        {
            string[] deleteStatus = new string[2];
            if (refresh)
                this.refresh();

            deleteStatus[0] = _character[id - 1, 42];
            deleteStatus[1] = _character[id - 1, 43];

            return deleteStatus;
        }

        public int getInventorySlots(int id, bool refresh = false)
        {
            int slots;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 44], out slots);

            return slots;
        }

        public bool getOnlineStatus(int id, bool refresh = false)
        {
            bool status = false;
            if (refresh)
                this.refresh();

            if (_character[id - 1, 47] == "1")
                status = true;

            return status;
        }

        public int getPvpState(int id, bool refresh = false)
        {
            int state;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 45], out state);

            return state;
        }

        public int getAction(int id, bool refresh = false)
        {
            int action;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 46], out action);

            return action;
        }

        public int[] getPkStatus(int id, bool refresh = false)
        {
            int[] pk = new int[3];
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 48], out pk[0]);
            Int32.TryParse(_character[id - 1, 49], out pk[1]);
            Int32.TryParse(_character[id - 1, 50], out pk[2]);

            return pk;
        }

        public string getGuideData(int id, bool refresh = false)
        {
            if (refresh)
                this.refresh();

            return _character[id - 1, 51];
        }

        public int getStallModel(int id, bool refresh = false)
        {
            int model;
            if (refresh)
                this.refresh();

            Int32.TryParse(_character[id - 1, 52], out model);

            return model;
        }

        public bool StorageExpanded(int id, bool refresh = false)
        {
            bool expanded = false;
            if (refresh)
                this.refresh();

            if (_character[id - 1, 53] == "1")
                expanded = true;

            return expanded;
        }

        public void createChar(string account, string name, int chartype, int volume, int level, int strength, int intellegence, int attribute, int hp, int mp, int gold, int experience, int spbar, int sp, int gm, int xsec, int ysec, int xpos, int ypos, int zpos, int s_hp, int s_mp, int min_phyatk, int max_phyatk, int min_magatk, int max_magatk, int phydef, int magdef, int hit, int parry, int walkspeed, int runspeed, int berserkspeed, int mag_absord, int phy_absord, int saverarea, int title, int deleted, string deletedtime, int invslots, int pvpstate, int action, int online, int dailypk, int pklevel, int murderlevel, int guidedata, int stallmodel, int storage_expanden)
        {
            // TODO!
        }

        public string[] getCharInfo(int id, bool refresh = false)
        {
            string[] character = new string[_character.GetLength(1)];

            for (int i = 0; i < character.Length; i++)
            {
                character[i] = _character[id - 1, i];
            }

            return character;
        }

        public string[,] getAllChars()
        {

            return this._character;
        }

        public void setConnection(MySqlConnection connection)
        {
            this.conn = connection;
        }

        public void refresh()
        {
            string[] columns = new string[1];
            columns[0] = "*";

            this._character = Query.SelectQuery(this.conn, "character", columns);
        }

        public string[,] Characters
        {
            get { return this._character; }
        }

        public void updateChar(int id)
        {
            Query.UpdateQuery(this.conn,"character","account,name,chartype,volume,level,strength,intellegence,attribute,hp,mp,gold,experience,spbar,sp,gm,xsec,ysec,xpos,ypos,zpos,s_hp,s_mp,min_phyatk,max_phyatk,min_magatk,max_magatk,phydef,magdef,hit,parry,walkspeed,runspeed,berserkspeed,berserkbar,mab_absord,phy_absord,save_area,title,deleted,deletedtime,Slots,Pvpstate,Action,Online,DailyPK,Pklevel,MurdeLevel,GuideData,StallModel,Storage_Expanded","","id=" + id.ToString()); //TODO!
        }

        public void setLevel(int id, int level)
        {
            Query.UpdateQuery(this.conn, "character", "level", level.ToString(), "id=" + id);
        }

        public void setStrength(int id, int strength)
        {
            Query.UpdateQuery(this.conn, "character", "strength", strength.ToString(), "id=" + id);
        }

        public void setIntellegence(int id, int intelligence)
        {
            Query.UpdateQuery(this.conn, "character", "intellegence", intelligence.ToString(), "id=" + id);
        }

        public void setAttribute(int id, int points)
        {
            Query.UpdateQuery(this.conn, "character", "attribute", points.ToString(), "id=" + id);
        }

        public void setMaxHP(int id, int hp)
        {
            Query.UpdateQuery(this.conn, "character", "hp", hp.ToString(), "id=" + id);
        }

        public void setMaxMP(int id, int mp)
        {
            Query.UpdateQuery(this.conn, "character", "mp", mp.ToString(), "id=" + id);
        }

        public void setGold(int id, int gold)
        {
            Query.UpdateQuery(this.conn, "character", "gold", gold.ToString(), "id=" + id);
        }

        public void setExperience(int id, int exp)
        {
            Query.UpdateQuery(this.conn, "character", "experience", exp.ToString(), "id=" + id);
        }

        public void setSpBar(int id, int bar)
        {
            Query.UpdateQuery(this.conn, "character", "spbar", bar.ToString(), "id=" + id);
        }

        public void setSP(int id, int sp)
        {
            Query.UpdateQuery(this.conn, "character", "sp", sp.ToString(), "id=" + id);
        }

        public void setXSec(int id, int sec)
        {
            Query.UpdateQuery(this.conn, "character", "xsec", sec.ToString(), "id=" + id);
        }

        public void setYSec(int id, int sec)
        {
            Query.UpdateQuery(this.conn, "character", "ysec", sec.ToString(), "id=" + id);
        }

        public void setXPos(int id, int pos)
        {
            Query.UpdateQuery(this.conn, "character", "xpos", pos.ToString(), "id=" + id);
        }

        public void setYPos(int id, int pos)
        {
            Query.UpdateQuery(this.conn, "character", "ypos", pos.ToString(), "id=" + id);
        }

        public void setZPos(int id, int pos)
        {
            Query.UpdateQuery(this.conn, "character", "zpos", pos.ToString(), "id=" + id);
        }

        public void setCurrentHP(int id, int hp)
        {
            Query.UpdateQuery(this.conn, "character", "s_hp", hp.ToString(), "id=" + id);
        }

        public void setCurrentMP(int id, int mp)
        {
            Query.UpdateQuery(this.conn, "character", "s_mp", mp.ToString(), "id=" + id);
        }

        public void setMinPhyAtk(int id, int atk)
        {
            Query.UpdateQuery(this.conn, "character", "min_phyatk", atk.ToString(), "id=" + id);
        }

        public void setMaxPhyAtk(int id, int atk)
        {
            Query.UpdateQuery(this.conn, "character", "max_phyatk", atk.ToString(), "id=" + id);
        }

        public void setMinMagAtk(int id, int atk)
        {
            Query.UpdateQuery(this.conn, "character", "min_magatk", atk.ToString(), "id=" + id);
        }

        public void setMaxMagAtk(int id, int atk)
        {
            Query.UpdateQuery(this.conn, "character", "max_magatk", atk.ToString(), "id=" + id);
        }

        public void setPhyDef(int id, int def)
        {
            Query.UpdateQuery(this.conn, "character", "phydef", def.ToString(), "id=" + id);
        }

        public void setMagDef(int id, int def)
        {
            Query.UpdateQuery(this.conn, "character", "magdef", def.ToString(), "id=" + id);
        }

        public void setHitRatio(int id, int hit)
        {
            Query.UpdateQuery(this.conn, "character", "hit", hit.ToString(), "id=" + id);
        }

        public void setParryRatio(int id, int parry)
        {
            Query.UpdateQuery(this.conn, "character", "parry", parry.ToString(), "id=" + id);
        }

        public void setWalkSpeed(int id, int speed)
        {
            Query.UpdateQuery(this.conn, "character", "walkspeed", speed.ToString(), "id=" + id);
        }

        public void setRunSpeed(int id, int speed)
        {
            Query.UpdateQuery(this.conn, "character", "runspeed", speed.ToString(), "id=" + id);
        }

        public void setBerserkSpeed(int id, int speed)
        {
            Query.UpdateQuery(this.conn, "character", "berserkspeed", speed.ToString(), "id=" + id);
        }

        public void setBerserkBar(int id, int bar)
        {
            Query.UpdateQuery(this.conn, "character", "berserkbar", bar.ToString(), "id=" + id);
        }

        public void setMagAbsord(int id, int absord)
        {
            Query.UpdateQuery(this.conn, "character", "mag_absord", absord.ToString(), "id=" + id);
        }

        public void setPhyAbsord(int id, int absord)
        {
            Query.UpdateQuery(this.conn, "character", "phy_absord", absord.ToString(), "id=" + id);
        }

        public void setSaveArea(int id, int area)
        {
            Query.UpdateQuery(this.conn, "character", "savearea", area.ToString(), "id=" + id);
        }

        public void setTitle(int id, int title)
        {
            Query.UpdateQuery(this.conn, "character", "title", title.ToString(), "id=" + id);
        }

        public void setDeleted(int id, int deleted)
        {
            Query.UpdateQuery(this.conn, "character", "deleted", deleted.ToString(), "id=" + id);
        }

        public void setDeletedTime(int id, string time)
        {
            Query.UpdateQuery(this.conn, "character", "deletedtime", time, "id=" + id);
        }

        public void setSlots(int id, int slots)
        {
            Query.UpdateQuery(this.conn, "character", "slots", slots.ToString(), "id=" + id);
        }

        public void setPVPState(int id, int state)
        {
            Query.UpdateQuery(this.conn, "character", "Pvpstate", state.ToString(), "id=" + id);
        }

        public void setAction(int id, int action)
        {
            Query.UpdateQuery(this.conn, "character", "Action", action.ToString(), "id=" + id);
        }

        public void setOnline(int id, int online)
        {
            Query.UpdateQuery(this.conn, "character", "Online", online.ToString(), "id=" + id);
        }

        public void setDailyPK(int id, int pk)
        {
            Query.UpdateQuery(this.conn, "character", "DailyPK", pk.ToString(), "id=" + id);
        }

        public void setPKLevel(int id, int level)
        {
            Query.UpdateQuery(this.conn, "character", "PkLevel", level.ToString(), "id=" + id);
        }

        public void setMurderLevel(int id, int level)
        {
            Query.UpdateQuery(this.conn, "character", "MurderLevel", level.ToString(), "id=" + id);
        }

        public void SetGuideData(int id, string data)
        {
            Query.UpdateQuery(this.conn, "character", "GuideData", data, "id=" + id);
        }

        public void setStallModel(int id, int model)
        {
            Query.UpdateQuery(this.conn, "character", "StallModel", model.ToString(), "id=" + id);
        }

        public void setStorageExpanded(int id, bool expanded)
        {
            if (expanded)
            {
                Query.UpdateQuery(this.conn, "character", "Storage_Expanded", "1", "id=" + id);
            }
            else
            {
                Query.UpdateQuery(this.conn, "character", "Storage_Expanded", "0", "id=" + id);
            }
        }
    }
}
